package cc.sunni.test;

import java.util.ArrayList;
import java.util.List;
import java.util.function.*;

/**
 * 方法引用
 *
 * @author jl
 * @since 2021/1/17 10:42
 */
public class MethodReference {

    public static void main(String[] args) {
        // ->左边是参数,右边是执行体
        Consumer<String> consumer = s -> System.out.println(s);
        // 当函数执行体里面只有一个函数调用,而且函数的参数和箭头左边是一样的,可以简写成方法引用的方式
        Consumer<String> stringConsumer = System.out::println;

        // 静态方法的引用:使用方法名
        Consumer<Hen> consumer1 = Hen::bark;
        Hen hen = new Hen("汤姆");
        consumer1.accept(hen);

        // 非静态方法的引用:使用对象实例
        Function<Integer, Integer> function = hen::eat;
        // 方法的输入和输出类型是一样的可以简写成一元函数接口
        UnaryOperator<Integer> unaryOperator = hen::eat;
        // jdk对基本类型进行了封装
        IntUnaryOperator intUnaryOperator = hen::eat;
        System.out.println("一天吃" + intUnaryOperator.applyAsInt(200) + "g的食物");

        // 非静态方法的引用:使用类名
        // BiFunction处理两个入参
        BiFunction<Hen, Integer, Integer> biFunction = Hen::eat;
        Integer apply = biFunction.apply(hen, 300);
        System.out.println("一天吃" + apply + "g的食物");

        // 构造函数的方法引用(无参),Supplier生产型函数接口
        Supplier<Hen> supplier = Hen::new;
        System.out.println("创建了一个新对象:" + supplier.get());
        // 构造函数的方法引用(有参)
        Function<String, Hen> stringHenFunction = Hen::new;
        Hen hen1 = stringHenFunction.apply("杰瑞");

        List<String> list = new ArrayList<>();
        list.add("0");
        test(list);
        System.out.println(list.size());


    }

    /**
     * 基本类型是值传递
     * 引用类型是传递的是对象的引用
     */
    private static void test(List<String> list) {
        // 对传入的参数进行了赋值操作,就相当于新建了一个对象,和原对象是两个不同对象,因此后续的操作不会影响原对象
        list = null;
        list.add("4");
        list.add("5");
    }
}

class Hen {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Hen() {
    }

    public Hen(String name) {
        this.name = name;
    }

    /**
     * 鸡叫
     */
    public static void bark(Hen hen) {
        System.out.println(hen.name + "大声尖叫");
    }

    /**
     * 进食
     * JDK默认把当前实例传入到非静态方法,参数名为this,位置是第一个,是可以省略的
     */
//    public int eat(Hen this, int i) {
    public int eat(int i) {
        System.out.println("名字叫:" + this.name);
        return i * 3;
    }
}

